package com.jeegod.ribbon.controller;

import com.jeegod.ribbon.command.HelloBatchCommand;
import com.jeegod.ribbon.command.HelloServiceCommand;
import com.jeegod.ribbon.service.HelloService;
import com.netflix.hystrix.strategy.concurrency.HystrixRequestContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

@RestController
public class ConsumerController {
    //注入负载均衡客户端

    @Autowired
    private LoadBalancerClient loadBalancerClient;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private HelloService helloService;

    @RequestMapping("/consumer")
    public String helloConsumer() throws ExecutionException, InterruptedException {
        //这里是根据配置文件的那个providers属性取的
        //ServiceInstance serviceInstance = loadBalancerClient.choose("providers");
        //负载均衡算法默认是轮询，轮询取得服务
       // URI uri = URI.create(String.format("http://%s:%s", serviceInstance.getHost(), serviceInstance.getPort()));
        //return restTemplate.getForEntity("http://HELLO-SERVICE1/hello", String.class).getBody();
        //return helloService.helloService();

        //List<String> list = new ArrayList<String>();
        //HelloServiceObserveCommand command = new HelloServiceObserveCommand("hello", restTemplate);

        //热执行
        //Observable<String> observable = command.observe();
        //冷执行
        //Observable<String> observable = command.toObservable();

        //Service注解执行
        /*Observable<String> observable = helloService.helloService();

        observable.subscribe(new Observer<String>() {
            @Override
            public void onCompleted() {
                System.out.println("汇聚完了所有查询请求");
            }

            @Override
            public void onError(Throwable throwable) {
                throwable.printStackTrace();
            }

            @Override
            public void onNext(String s) {
                System.out.println("结果来了:" + s);
                list.add(s);
            }
        });
        return list.toString();*/

        //Hystrix的缓存实现，这功能有点鸡肋
        HystrixRequestContext.initializeContext();
        HelloServiceCommand command = new HelloServiceCommand("hello", restTemplate);
        String execute = command.execute();
        HelloServiceCommand command1 = new HelloServiceCommand("hello", restTemplate);
        String execute1 = command1.execute();
        //清理缓存
        //HystrixRequestCache.getInstance("hello").clear();
        return execute + " , " + execute1;
    }

    @RequestMapping("/combine")
    public String combine() throws ExecutionException, InterruptedException {
        // 请求合并
        HystrixRequestContext context = HystrixRequestContext.initializeContext();
        HelloBatchCommand command1 = new HelloBatchCommand(restTemplate, 1L);
        HelloBatchCommand command2 = new HelloBatchCommand(restTemplate, 2L);
        HelloBatchCommand command3 = new HelloBatchCommand(restTemplate, 3L);

        // 这里你必须要异步，因为同步是一个请求完后另一个才能继续执行，所以必须要异步才能请求合并
        Future<String> future1 = command1.queue();
        Future<String> future2 = command2.queue();

        String r1 = future1.get();
        String r2 = future2.get();

        Thread.sleep(2000);

        // 可以看到前面两条命令会合并，最后一条会单独，因为睡了2000毫秒，而你请求设置要求在200毫秒内才合并的。
        Future<String> future3 = command3.queue();
        String r3 = future3.get();

        System.out.println("result1:" + r1);
        System.out.println("result2:" + r2);
        System.out.println("result3:" + r3);

        context.close();
        return "result1:" + r1 + "," + "result2:" + r2 + "," + "result3:" + r3;
    }

    @RequestMapping("/annonCombine")
    public String annonCombine() throws ExecutionException, InterruptedException {
        // 请求合并
        HystrixRequestContext context = HystrixRequestContext.initializeContext();

        Future<String> future1 = helloService.batchGetHjc(1L);
        Future<String> future2 = helloService.batchGetHjc(2L);

        String r1 = future1.get();
        String r2 = future2.get();

        Thread.sleep(2000);

        Future<String> future3 = helloService.batchGetHjc(3L);
        String r3 = future3.get();

        System.out.println("result1:" + r1);
        System.out.println("result2:" + r2);
        System.out.println("result3:" + r3);

        context.close();
        return "result1:" + r1 + "," + "result2:" + r2 + "," + "result3:" + r3;
    }
}
